package client;

import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;

import javax.swing.JTable;
import javax.swing.JTextArea;
import common.*;

public abstract class ClientThread extends Thread
{
	/*
    private String address;
    private int port;
    
    ClientThread(String _address, JTextArea out)
    {
        this.cs = cs;
    }
    
    @Override
    public void run() {
    	
    }
    
    synchronized public void sendObject(Object sm){
        try{
        	OutputStream os = cs.getOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(os);
            oos.writeObject(sm);
            oos.flush();
        }catch (IOException e){
        	//out.Append(e.getMessage());
        }
    }
    */
	
    protected String address;
    protected int port;
    protected Socket cs = null;
    
    protected Socket Connect(String address, int port)
	{
		OutputStream os;
		InputStream is;
		
		try {
			cs = new Socket(address, port);
			
            is = cs.getInputStream();
			os = cs.getOutputStream();
			
			SendUUID sID;
			
			sID = (SendUUID) ReceiveObject(Commands.UUIDRequest);
			System.out.println(sID.idUser);
		} catch (UnknownHostException e) {
			// TODO Auto-generated catch block
			return null;
		} catch (java.net.ConnectException e) {
			return null;
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return null;
		}
		
		return cs;
	}
	
	protected void Disconnect(Socket cs)
	{
        try{
            OutputStream os = cs.getOutputStream();
            os.write(Commands.UnlinkRequest);
            os.flush();
            cs.close();
        } catch(IOException e){
        	e.printStackTrace();
			return;
        }
	}
	
	protected Object ReceiveObject(int command)
    {    	
		OutputStream os;
		InputStream is;
		
		Object obj = null;
        
		try {
			is = cs.getInputStream();
	        os = cs.getOutputStream();
	        
	        os.write(command);
	        os.flush();
	        
	        ObjectInputStream ois = new ObjectInputStream(is);
	        
			obj = ois.readObject();
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return null;
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return obj;
    }
	
	protected Object ReceiveObject()
    {    	
		OutputStream os;
		InputStream is;
		
		Object obj = null;
        
		try {
			is = cs.getInputStream();
	        os = cs.getOutputStream();
	        
	        ObjectInputStream ois = new ObjectInputStream(is);
	        
			obj = ois.readObject();
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return null;
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return obj;
    }
	
	protected void SendObject(int command, Object obj)
    {
		OutputStream os;
		InputStream is;
		
        try {
			//is = cs.getInputStream();
	        os = cs.getOutputStream();
	        
			os.write(command);
	        os.flush();
	        	        
	        ObjectOutputStream oos = new ObjectOutputStream(os);
	        oos.writeObject(obj);
	        oos.flush();
        }
			catch(java.lang.ArrayIndexOutOfBoundsException e)
			{
				System.out.println("run");
			}
		catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return;
		}
    }
	
	protected void SendObject(Object obj)
    {
		OutputStream os;
		InputStream is;
		
        try {
			//is = cs.getInputStream();
	        os = cs.getOutputStream();
	       
	        	        
	        ObjectOutputStream oos = new ObjectOutputStream(os);
	        oos.writeObject(obj);
	        oos.flush();
        }
			catch(java.lang.ArrayIndexOutOfBoundsException e)
			{
				System.out.println("run");
			}
		catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return;
		}
    }
}

class SendingClientThread extends ClientThread
{	 
	private int command;
	private Object obj;
	private Client client = null;
	private JTable table = null;
	
	public SendingClientThread(String address, int port, int command, Object obj)
    {
        super.address = address;
        super.port = port;
        
        this.command = command;
        this.obj = obj;       
    }
    
	/*
	public SendingClientThread(String address, int port, int command, Object obj, Client client)
    {
        super.address = address;
        super.port = port;
        
        this.command = command;
        this.obj = obj; 
        
        this.client = client;
    }
	*/
	
	public SendingClientThread(String address, int port, int command, Object obj, JTable table)
    {
        super.address = address;
        super.port = port;
        
        this.command = command;
        this.obj = obj; 
        
        this.table = table;
    }
	

	
    @Override
    public void run()
    {
    	try{
    		Connect(address, port);
    	SendObject(command, obj);
    	}
		catch(java.lang.ArrayIndexOutOfBoundsException e)
		{
		System.out.println("run.1");
		}

    	if (table != null)
    	{    		    		
    		
    		MyTableModel tableModel = null;
    		SendTableModel so = null;
			try {
				/*
				tableModel = null;
				OutputStream os;
				InputStream is;
				
				is = cs.getInputStream();
		        
		        os = cs.getOutputStream();
		        os.write(Commands.SendTableRequest);
		        
		        ObjectInputStream ois = new ObjectInputStream(is);
		        so = (SendTableModel) ois.readObject();
		        
				tableModel = so.tableModel;
				table.setModel(tableModel);
				*/
    		
				Disconnect(cs);
			}
			catch(java.lang.ArrayIndexOutOfBoundsException e)
			{
				System.out.println("run");
			}
			/*
			catch (IOException | ClassNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();	
				System.out.println("run");
			}
			*/
    	}
    }
}

class ReceivingClientThread extends ClientThread
{
	private int command;
	public Object obj = null;
	private SendDownloadRequest request = null;
	
	public ReceivingClientThread(String address, int port, int command, SendDownloadRequest request)
    {
        super.address = address;
        super.port = port;
        
        this.command = command;
        this.request = request;
    }
    
    @Override
    public void run()
    {
    	Connect(address, port);
    	SendObject(Commands.DownloadRequest, request);
    	obj = ReceiveObject();
    	Disconnect(cs);
    }
}